#ifndef __USER_THREADS_EXPORT
#define __USER_THREADS_EXPORT


#include <unistd.h> /* useconds_t */

#include "user_threads.h" /* thread_id */
#include "user_mutex.h" /* uthread_mutex_t */

#include "linked_list.h"

#ifndef useconds_t
#define useconds_t unsigned long
#endif

#define NR_THREADS 200

#define UTHREAD_MIN_PRIO (0)
#define UTHREAD_MAX_PRIO (8)

#define UTHREAD_RUNNING (0)
#define UTHREAD_SUSPENDED (1)
#define UTHREAD_ZOMBIE (2)

#define UTHREAD_TIME_SLICE (1)

int uthread_init();


typedef useconds_t lock_t;
    /* TODO: check why this does not work on the VM (__useconds_t works...). --Ofer*/

void mask_interrupts(lock_t *);
void unmask_interrupts(lock_t *);
void wake_up_uthread(thread_id);
void suspend_uthread();


uthread_mutex_t _thread_peek_waiting(thread_id t);
/*  Returns the mutex that 't' was waiting for - or NULL if 't' is not waiting
	for any mutex.
*/

uthread_mutex_t _thread_peek_locking(thread_id t);
/*
  Returns the 'front' of the list 'mutexes_locking' of 't', or NULL if 't' does
	not currently lock any mutexes.
*/

void _thread_mutex_wait(thread_id t, uthread_mutex_t m);
void _thread_mutex_clear_wait(thread_id t);
/* The user_mutex model must call this function each time a uthread goes out
	to wait for a mutex.
*/

int _thread_mutex_lock(thread_id t, uthread_mutex_t m);
/* The user_mutex model must call this function each time a uthread locks a
	mutex. Meaning: when the thread 't' locks the (previously unlocked) mutex
	for the first time.

	On success: returns 0.
*/

void _thread_mutex_unlock(thread_id t, uthread_mutex_t m);
/* The user_mutex model must call this function each time a uthread unlocks a
	mutex (meaning: when the thread 't' unlocks the mutex completely, and it is
	no longer locked).
*/

#endif

